﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Threading;
using System.Net;
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
using System.Web.Caching;
using System.Runtime.Serialization.Formatters.Binary;

namespace webQQservice
{
    public class Global : System.Web.HttpApplication
    {
        public static Thread thread;
        public static string visert;
        public static string path;
        public static bool login = false;
        public static string cookie, ptwebqq, clientid, psessionid, vfwebqq;
        public static QQData item ;
       public static Dictionary<string, string> friendList = new Dictionary<string, string>();//保存好友id值集合
       //public static System.Timers.Timer myTimer = new System.Timers.Timer();
      // public static System.Timers.Timer Timer = new System.Timers.Timer();
       private static string tempPath = "temp.dat";
       private static bool islog = false;
       void Application_Start(object sender, EventArgs e)
       {
           path = Server.MapPath("/") + "yanzheng.jpg";
           tempPath = Server.MapPath("/") + tempPath;
           log("网站启动");
           start();
       }

        private static void start()
        {
            CacheTimer registTimer = new CacheTimer();
            registTimer.RegistCacheTimmer();
            
            thread = new Thread(new ThreadStart(LoginSelect));
            thread.IsBackground = true;
            thread.Start();
        }
        public static void log(string txt)
        {
            if (islog == false)
                return;
            StreamWriter sw = new StreamWriter(tempPath + "txt",true);
            sw.WriteLine(txt+DateTime.Now.ToString());
            sw.Close();
        }
        private static void LoginSelect()
        {
                if (File.Exists(tempPath) == false)//序列号文件不存在
                {
                    try
                    {

                        item = new QQData();
                        item.QQ = "2441607675";
                        item.Passwd = "123456789";
                        item.ReadyStatus = "我在线上";

                    Retry:

                        if (QQHelp.GetVerfyCode(item.QQ, out cookie) == true)
                        {
                            Global.thread.Suspend();

                            if (visert == null)//跳过这条登录
                                return;
                        }


                        ptwebqq = clientid = psessionid = vfwebqq = string.Empty;
                        string msg = string.Empty;
                        bool success = QQHelp.Login(item.QQ, item.Passwd, visert, item.ReadyStatus, ref cookie, ref ptwebqq, ref clientid, ref psessionid, ref vfwebqq, ref msg);
                        if (success)//登录成功
                        {

                            
                            item.RefreshStart = DateTime.Now;
                            item.Status = item.ReadyStatus;
                            item.Cookie = cookie;
                            item.ClientId = clientid;
                            item.Ptwebqq = ptwebqq;
                            item.Psessionid = psessionid;
                            item.Vfwebqq = vfwebqq;
                            item.RefreshComplete = true;


                            //获取昵称
                            string url1 = "http://s.web2.qq.com/api/get_friend_info2?tuin=" + item.QQ + "&verifysession=&code=&vfwebqq=" + vfwebqq + "&t=" + DateTime.Now.ToFileTime();
                            string nickName = HttpHelp.GetHtml(url1, "http://s.web2.qq.com/proxy.html?v=20110412001&callback=1&id=2", ref cookie, Encoding.UTF8, false);
                            nickName = nickName.Remove(0, nickName.IndexOf("nick\":\"") + 7);
                            nickName = nickName.Substring(0, nickName.IndexOf("\","));


                            try
                            {
                                getFrendList();//获取好友列表

                                FileStream fileStream = new FileStream(tempPath, FileMode.Create);
                                BinaryFormatter b = new BinaryFormatter();
                                b.Serialize(fileStream, item);
                                fileStream.Close();
                                FileStream fileStream2 = new FileStream(tempPath+"s", FileMode.Create);
                                BinaryFormatter c = new BinaryFormatter();
                                c.Serialize(fileStream2, friendList);
                                fileStream2.Close();
                                log("QQ登录成功");
                                login = true;
                            }
                            catch (Exception ex)
                            {

                            }


                        }
                        else//验证码无效
                        {
                            goto Retry;
                        }

                    }


                    catch (Exception ex)
                    {
                        //MessageBox.Show(ex.Message);
                    }
                    //lvMain.Enabled = true;



                }
                else//序列号文件存在
                {
                    FileStream fileStream = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    BinaryFormatter b = new BinaryFormatter();
                    item = b.Deserialize(fileStream) as QQData;
                    fileStream.Close();
                    //if (friendList.Count == 0)
                    //    getFrendList();
                    FileStream fileStream2 = new FileStream(tempPath+"s", FileMode.Open, FileAccess.Read, FileShare.Read);
                    BinaryFormatter c = new BinaryFormatter();
                    friendList = c.Deserialize(fileStream2) as Dictionary<string, string>;
                    fileStream2.Close();
                    log("读取缓存文件成功");
                    login = true;
                }
        }

        private static void getFrendList()
        {
            //获取好友列表
            string postData = "r={\"h\":\"hello\",\"vfwebqq\":\"" + vfwebqq + "\"}";
            WebHeaderCollection header;
            string html2 = HttpHelp.GetHtml("http://s.web2.qq.com/api/get_user_friends2", "http://s.web2.qq.com/proxy.html?v=20110412001&callback=1&id=2", postData, ref cookie, true, out header, "application/x-www-form-urlencoded; charset=UTF-8", Encoding.UTF8, false);
            if (html2.Contains("{\"retcode\":100000}"))
            {
                
                log("获取好友列表失败");return;
            }


            Regex friend = new Regex("({\"flag\":)(?<flag>[0-9]{1,2}?)(,\"uin\":)(?<uin>[0-9]{5,11}?)(,\"categories\":)(?<id>[0-9]{1,2}?)(})");
            foreach (Match match in friend.Matches(html2))
            {
                friendList.Add(QQHelp.GetQQByUid(item.Cookie, match.Groups["uin"].Value, item.Vfwebqq), match.Groups["uin"].Value);
            }
        }

      //private static  void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
      //  {
      //      HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["site"]);
      //      HttpWebResponse hw = (HttpWebResponse)hr.GetResponse();
      //     // QQHelp.SendMsg(cookie, friendList["360902777"],  hw.StatusDescription, clientid, psessionid);
      //  }
      void Application_End(object sender, EventArgs e)
      {
          //  在应用程序关闭时运行的代码

          //HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["site"]);
          //HttpWebResponse hw = (HttpWebResponse)hr.GetResponse();
          log("程序退出");
          if (login == true)
          {
              string msg = "退出！";
              QQHelp.SendMsg(cookie, friendList["360902777"], DateTime.Now.ToString()+"web程序结束", clientid, psessionid);
              Thread.Sleep(10000);
              QQHelp.Logout(item.Cookie, item.ClientId, item.Psessionid, ref msg);
              log("QQ登出");
          }
      }

        void Application_Error(object sender, EventArgs e)
        {
            // 在出现未处理的错误时运行的代码

        }

        void Session_Start(object sender, EventArgs e)
        {
            // 在新会话启动时运行的代码

        }
        void Application_BeginRequest(Object sender, EventArgs e)
        {
            CacheTimer registTimer = new CacheTimer();
            log("新建回话，刷新缓存");
            registTimer.RegistCacheTimmer();
        }
        void Session_End(object sender, EventArgs e)
        {
            // 在会话结束时运行的代码。 
            // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
            // InProc 时，才会引发 Session_End 事件。如果会话模式设置为 StateServer 
            // 或 SQLServer，则不会引发该事件。

        }

        //通过定时检测是否有qq消息返回，刷新session，保持在线
        public static void RefreshSession()
        {
            //QQData item = item as QQData;
            log("刷新消息");
            if (item == null)
            {
                FileStream fileStream = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                BinaryFormatter b = new BinaryFormatter();
                item = b.Deserialize(fileStream) as QQData;
                fileStream.Close();
                login = true;
            }
            string cookie = item.Cookie;

            string url = "http://d.web2.qq.com/channel/poll2?key=0&clientid=" + item.ClientId + "&psessionid=" + item.Psessionid + "&t=" + DateTime.Now.ToFileTime();
            string html = GetHtml(url, "http://d.web2.qq.com/proxy.html?v=20110331002&callback=2", ref cookie, Encoding.UTF8, false);

            if (html.Contains ( "{\"retcode\":121"))
            {
                //已下线
                log("QQ非正常退出");
                login = false;
                if (File.Exists(tempPath))
                    File.Delete(tempPath);
                if (File.Exists(path))
                    File.Delete(path);
                
                return;
            }
            if (html.Contains(@"\u60A8\u7684\u8D26\u53F7\u5728\u53E6\u4E00\u5730\u70B9\u767B\u5F55\uFF0C\u60A8\u5DF2\u88AB\u8FEB\u4E0B\u7EBF\u3002\u5982\u6709\u7591\u95EE\uFF0C\u8BF7\u767B\u5F55"))
            {
             //别处登录
                login = false;
                QQData data = new QQData();
                data.QQ = item.QQ;
                data.Passwd = item.Passwd;
                data.ReadyStatus = item.ReadyStatus;
                data.RefreshComplete = true;
                
               
            }
            else if (html.Contains("poll_type\":\"message"))
            {
              //收到消息
                log("QQ收到消息");
                string from_uin = "", to_uin = "", content = "";

                html = html.Remove(0, html.IndexOf("from_uin\":") + 10);
                from_uin = html.Substring(0, html.IndexOf(",\"to_uin"));

                html = html.Remove(0, html.IndexOf("to_uin\":") + 8);
                to_uin = html.Substring(0, html.IndexOf(",\"msg_id2"));

                html = html.Remove(0, html.IndexOf("\"name\":"));
                html = html.Remove(0, html.IndexOf(",\"") + 2);
                content = HttpHelp.ConvertUnicodeStringToChinese(html.Substring(0, html.IndexOf("\"]")));

                string fromQQ = QQHelp.GetQQByUid(item.Cookie, from_uin, item.Vfwebqq);//获取真实qq号码
                //如果有备注显示备注名称，没有备注显示昵称
                string nickname = "";
                if (item.friends.ContainsKey(from_uin))
                    nickname = item.friends[from_uin];
              
                QQHelp.SendMsg(item.Cookie, from_uin, DateTime.Now.ToString()+"收到消息", item.ClientId, item.Psessionid);
            }
            //QQHelp.SendMsg(item.Cookie, friendList["360902777"], DateTime.Now.ToString()+"刷新完成", item.ClientId, item.Psessionid);
            item.RefreshComplete = true;//刷新消息完毕
        }
        public static string GetHtml(string url, string referer, ref string cookie, Encoding encoding, bool getResponseCookie)
        {
            string html = string.Empty;
            HttpWebRequest webRequest = null;
            HttpWebResponse response = null;
            try
            {
                webRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                webRequest.Headers[HttpRequestHeader.Cookie] = cookie;
                webRequest.Referer = referer;
                webRequest.KeepAlive = false;
                webRequest.Timeout = 15000;//超时时间
                webRequest.Method = "GET";
                webRequest.ContentType = "utf-8";
                webRequest.Headers.Set("Accept-Language", "zh-cn,zh;q=0.5");
                webRequest.Headers.Set("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");
                webRequest.Headers.Set("Cache-Control", "no-cache");
                webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                webRequest.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1";

                response = (HttpWebResponse)webRequest.GetResponse();
                using (Stream getStream = response.GetResponseStream())
                {
                    using (StreamReader streamReader = new StreamReader(getStream, encoding))
                    {
                        html = streamReader.ReadToEnd();
                    }
                }
                if (getResponseCookie)
                    cookie = response.Headers[HttpResponseHeader.SetCookie];
            }
            catch (WebException)
            {
                //html = "{\"retcode\":0,\"result\":[{\"poll_type\":\"message\",\"value\":{\"msg_id\":6396,\"from_uin\":1010310736,\"to_uin\":2441607675,\"msg_id2\":930943,\"msg_type\":9,\"reply_ip\":176881869,\"time\":1318218369,\"content\":[[\"font\",{\"size\":10,\"color\":\"8080c0\",\"style\":[0,0,0],\"name\":\"\u5B8B\u4F53\"}],\"23 \"]}}]}";
                html = "";
                log("等待服务器回应超时");
            }
            catch (Exception)
            {
                html = "";
            }
            finally
            {
                if (webRequest != null)
                    webRequest.Abort();
                if (response != null)
                    response.Close();
            }
            return html;
        }

        private static void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            //try
            //{
            //    if (login)
            //    {
            //        RefreshSession(item);
                  
            //    }
            //}
            //catch (Exception ex)
            //{
 
            //}
        }
    }
}
